from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import os
import uuid

# 初始化Flask应用
app = Flask(__name__)
# 解决跨域问题
CORS(app)

# 配置MySQL数据库连接
# 格式：mysql+pymysql://用户名:密码@主机地址:端口号/数据库名
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@localhost:3306/admin_system'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # 关闭SQLAlchemy的修改跟踪功能

# 配置文件上传
UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# 确保上传目录存在
if not os.path.exists(UPLOAD_FOLDER):
    os.makedirs(UPLOAD_FOLDER)

# 初始化数据库
db = SQLAlchemy(app)


# 定义数据模型
class User(db.Model):
    """用户模型"""
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    avatar = db.Column(db.String(200), nullable=True)  # 头像文件名
    created_at = db.Column(db.DateTime, default=datetime.now)

    def to_dict(self):
        """将模型实例转换为字典，方便JSON序列化"""
        return {
            'id': self.id,
            'username': self.username,
            'email': self.email,
            'avatar': self.avatar,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S')
        }


class Item(db.Model):
    """数据项模型，用于CRUD操作演示"""
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text, nullable=True)
    created_at = db.Column(db.DateTime, default=datetime.now)

    def to_dict(self):
        """将模型实例转换为字典，方便JSON序列化"""
        return {
            'id': self.id,
            'name': self.name,
            'description': self.description,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S')
        }


class UploadedFile(db.Model):
    """上传文件模型，记录上传的文件信息"""
    id = db.Column(db.Integer, primary_key=True)
    original_name = db.Column(db.String(200), nullable=False)  # 原始文件名
    unique_name = db.Column(db.String(200), nullable=False)  # 唯一文件名（避免冲突）
    upload_time = db.Column(db.DateTime, default=datetime.now)

    def to_dict(self):
        """将模型实例转换为字典"""
        return {
            'id': self.id,
            'original_name': self.original_name,
            'unique_name': self.unique_name,
            'upload_time': self.upload_time.strftime('%Y-%m-%d %H:%M:%S'),
            'file_path': f'/uploads/{self.unique_name}'
        }


# 创建数据库表（首次运行时需要）
with app.app_context():
    db.create_all()


# 基础CRUD接口 - 创建数据
@app.route('/api/data', methods=['POST'])
def create_data():
    """创建新数据"""
    data = request.json

    # 验证必要字段
    if not data or 'name' not in data:
        return jsonify({'error': '缺少必要字段'}), 400

    # 创建新数据条目
    new_item = Item(
        name=data['name'],
        description=data.get('description', '')  # 可选字段
    )

    # 保存到数据库
    try:
        db.session.add(new_item)
        db.session.commit()
        return jsonify(new_item.to_dict()), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': f'创建数据失败: {str(e)}'}), 500


# 基础CRUD接口 - 获取所有数据
@app.route('/api/data', methods=['GET'])
def get_all_data():
    """获取所有数据"""
    items = Item.query.all()
    return jsonify([item.to_dict() for item in items])


# 基础CRUD接口 - 获取单条数据
@app.route('/api/data/<int:item_id>', methods=['GET'])
def get_data(item_id):
    """获取指定ID的数据"""
    item = Item.query.get(item_id)
    if item:
        return jsonify(item.to_dict())
    return jsonify({'error': '数据不存在'}), 404


# 基础CRUD接口 - 更新数据
@app.route('/api/data/<int:item_id>', methods=['PUT'])
def update_data(item_id):
    """更新指定ID的数据"""
    data = request.json
    item = Item.query.get(item_id)

    if not item:
        return jsonify({'error': '数据不存在'}), 404

    if not data:
        return jsonify({'error': '没有提供更新数据'}), 400

    try:
        # 更新字段
        if 'name' in data:
            item.name = data['name']
        if 'description' in data:
            item.description = data['description']

        db.session.commit()
        return jsonify(item.to_dict())
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': f'更新数据失败: {str(e)}'}), 500


# 基础CRUD接口 - 删除数据
@app.route('/api/data/<int:item_id>', methods=['DELETE'])
def delete_data(item_id):
    """删除指定ID的数据"""
    item = Item.query.get(item_id)

    if not item:
        return jsonify({'error': '数据不存在'}), 404

    try:
        db.session.delete(item)
        db.session.commit()
        return jsonify({'message': '数据已删除'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': f'删除数据失败: {str(e)}'}), 500


# 用户管理接口 - 获取所有用户
@app.route('/api/users', methods=['GET'])
def get_all_users():
    """获取所有用户"""
    users = User.query.all()
    return jsonify([user.to_dict() for user in users])


# 用户管理接口 - 创建新用户
@app.route('/api/users', methods=['POST'])
def create_user():
    """创建新用户"""
    data = request.json

    # 验证必要字段
    if not data or 'username' not in data or 'email' not in data:
        return jsonify({'error': '缺少必要字段'}), 400

    # 检查用户名和邮箱是否已存在
    existing_user = User.query.filter(
        (User.username == data['username']) | (User.email == data['email'])
    ).first()
    
    if existing_user:
        return jsonify({'error': '用户名或邮箱已存在'}), 400

    # 创建新用户
    new_user = User(
        username=data['username'],
        email=data['email'],
        avatar=data.get('avatar', '')  # 可选字段
    )

    # 保存到数据库
    try:
        db.session.add(new_user)
        db.session.commit()
        return jsonify(new_user.to_dict()), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': f'创建用户失败: {str(e)}'}), 500


# 用户管理接口 - 获取单个用户
@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    """获取指定ID的用户"""
    user = User.query.get(user_id)
    if user:
        return jsonify(user.to_dict())
    return jsonify({'error': '用户不存在'}), 404


# 用户管理接口 - 更新用户信息
@app.route('/api/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
    """更新指定ID的用户信息"""
    data = request.json
    user = User.query.get(user_id)

    if not user:
        return jsonify({'error': '用户不存在'}), 404

    if not data:
        return jsonify({'error': '没有提供更新数据'}), 400

    try:
        # 检查用户名和邮箱唯一性（排除当前用户）
        if 'username' in data and data['username'] != user.username:
            existing_user = User.query.filter(User.username == data['username']).first()
            if existing_user:
                return jsonify({'error': '用户名已存在'}), 400
            user.username = data['username']
            
        if 'email' in data and data['email'] != user.email:
            existing_user = User.query.filter(User.email == data['email']).first()
            if existing_user:
                return jsonify({'error': '邮箱已存在'}), 400
            user.email = data['email']
            
        if 'avatar' in data:
            user.avatar = data['avatar']

        db.session.commit()
        return jsonify(user.to_dict())
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': f'更新用户失败: {str(e)}'}), 500


# 用户管理接口 - 删除用户
@app.route('/api/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
    """删除指定ID的用户"""
    user = User.query.get(user_id)

    if not user:
        return jsonify({'error': '用户不存在'}), 404

    try:
        db.session.delete(user)
        db.session.commit()
        return jsonify({'message': '用户已删除'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': f'删除用户失败: {str(e)}'}), 500


# 文件上传接口
@app.route('/api/upload', methods=['POST'])
def upload_file():
    """处理文件上传"""
    # 检查是否有文件被上传
    if 'file' not in request.files:
        return jsonify({'error': '没有文件被上传'}), 400

    file = request.files['file']

    # 检查文件名是否为空
    if file.filename == '':
        return jsonify({'error': '未选择文件'}), 400

    # 如果文件有效
    if file:
        try:
            # 生成唯一文件名，避免冲突
            unique_filename = f"{uuid.uuid4().hex}_{file.filename}"
            file_path = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename)

            # 保存文件
            file.save(file_path)

            # 记录到数据库
            uploaded_file = UploadedFile(
                original_name=file.filename,
                unique_name=unique_filename
            )
            db.session.add(uploaded_file)
            db.session.commit()

            # 返回文件信息
            return jsonify(uploaded_file.to_dict()), 201
        except Exception as e:
            db.session.rollback()
            return jsonify({'error': f'文件上传失败: {str(e)}'}), 500


# 获取已上传文件列表
@app.route('/api/files', methods=['GET'])
def get_uploaded_files():
    """获取所有已上传的文件信息"""
    files = UploadedFile.query.order_by(UploadedFile.upload_time.desc()).all()
    return jsonify([file.to_dict() for file in files])


# 提供上传文件的访问
@app.route('/uploads/<filename>')
def uploaded_file(filename):
    """访问已上传的文件"""
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)


# 启动服务器
if __name__ == '__main__':
    app.run(debug=True)
